/*
 * Copyright (c) 2011-2014, fortiss GmbH.
 * Licensed under the Apache License, Version 2.0.
 *
 * Use, modification and distribution are subject to the terms specified
 * in the accompanying license file LICENSE.txt located at the root directory
 * of this software distribution. A copy is available at
 * http://chromosome.fortiss.org/.
 *
 * This file is part of CHROMOSOME.
 *
 * $Id: loginClientSendRequestFunction.c 7837 2014-03-14 12:33:13Z wiesmueller $
 */

/**
 * \file
 *         Source file for function loginClientSendRequest in component loginClient.
 *
 * \author
 *         This file has been generated by the CHROMOSOME Modeling Tool (XMT)
 *         (fortiss GmbH).
 */

/******************************************************************************/
/***   Includes                                                             ***/
/******************************************************************************/
#include "xme/core/login/include-gen/loginClientSendRequestFunction.h"

#include "xme/core/login/include-gen/loginClientSendRequestFunctionWrapper.h"
#include "xme/core/login/include-gen/loginClientComponent.h"
#include "xme/core/login/include-gen/loginClientComponentWrapper.h"
#include "xme/core/login/include-gen/loginClientManifest.h"

#include "xme/core/logUtils.h"

// PROTECTED REGION ID(XME_CORE_LOGIN_LOGINCLIENTSENDREQUESTFUNCTION_C_INCLUDES) ENABLED START

#include "xme/core/login/include/loginClient.h"

#include "xme/hal/include/time.h"

// PROTECTED REGION END

/******************************************************************************/
/***   Definitions                                                          ***/
/******************************************************************************/

// PROTECTED REGION ID(XME_CORE_LOGIN_LOGINCLIENTSENDREQUESTFUNCTION_C_DEFINITIONS) ENABLED START

// PROTECTED REGION END

/******************************************************************************/
/***   Variables                                                            ***/
/******************************************************************************/
/**
 * \brief  Variable holding the value of the required output port 'outRequest'.
 *
 * \details If necessary initialize this in the init function.
 *          The value of this variable will be written to the port at the end of
 *          the step function.
 */
static xme_core_topic_login_loginRequest_t
portOutRequestData;

// PROTECTED REGION ID(XME_CORE_LOGIN_LOGINCLIENTSENDREQUESTFUNCTION_C_VARIABLES) ENABLED START

/**
 * \brief Variable holding the time interval after which a login request will be
 *        sent again, if not successful.
 *
 * \details Initialized in xme_core_login_loginClientSendRequestFunction_init().
 */
static xme_hal_time_timeInterval_t retryInterval;

/**
 * \brief Time value in milli seconds for retryInterval.
 */
static const uint64_t retryPeriodInMs = 20000ull;

// PROTECTED REGION END

/******************************************************************************/
/***   Prototypes                                                           ***/
/******************************************************************************/

// PROTECTED REGION ID(XME_CORE_LOGIN_LOGINCLIENTSENDREQUESTFUNCTION_C_PROTOTYPES) ENABLED START

// PROTECTED REGION END

/******************************************************************************/
/***   Implementation                                                       ***/
/******************************************************************************/
xme_status_t
xme_core_login_loginClientSendRequestFunction_init
(
    xme_core_login_loginClientComponent_config_t* const componentConfig
)
{
    // PROTECTED REGION ID(XME_CORE_LOGIN_LOGINCLIENTSENDREQUESTFUNCTION_INITIALIZE_C) ENABLED START
    xme_status_t initStatus;
    xme_status_t fillLoginRequestStatus;

    XME_UNUSED_PARAMETER(componentConfig);

    initStatus = xme_core_login_loginClient_init();

    retryInterval = xme_hal_time_timeIntervalFromMilliseconds(retryPeriodInMs);

    if (XME_STATUS_SUCCESS != initStatus)
    {
        XME_LOG
        (
            XME_LOG_NOTE,
            "[LoginClient] Cannot init the login client. Return status: %d \n",
            initStatus
        );
    }

    fillLoginRequestStatus = xme_core_login_loginClient_fillLoginRequest(&portOutRequestData);

    if (XME_STATUS_SUCCESS != fillLoginRequestStatus)
    {
        XME_LOG
        (
            XME_LOG_NOTE,
            "[LoginClient] Cannot fill login request. Return status: %d \n",
            fillLoginRequestStatus
        );
    }

    return XME_STATUS_SUCCESS;

    // PROTECTED REGION END
}

void
xme_core_login_loginClientSendRequestFunction_step
(
    xme_core_login_loginClientComponent_config_t* const componentConfig
)
{
    xme_status_t status[1];
    
    xme_core_topic_login_loginRequest_t* portOutRequestDataPtr = &portOutRequestData;
    
    {
        // PROTECTED REGION ID(XME_CORE_LOGIN_LOGINCLIENTSENDREQUESTFUNCTION_STEP_C) ENABLED START

        static xme_hal_time_timeHandle_t lastRequestTime; // Time when we sent the last request
        static bool doSend = true; // Whether we will send the request
        xme_core_node_nodeId_t nodeID = xme_core_node_getCurrentNodeId();

        XME_UNUSED_PARAMETER(componentConfig);

        portOutRequestDataPtr = NULL;

        // When the node has a valid node ID, then the login was successful
        if (XME_CORE_NODE_INVALID_NODE_ID == nodeID)
        {
            if (doSend)
            {
                lastRequestTime = xme_hal_time_getCurrentTime();

                XME_LOG(XME_LOG_NOTE, "[loginClientSendRequestFunction] Broadcasting a Login Request\n");

                portOutRequestDataPtr = &portOutRequestData;

                doSend = false;
            }
            else
            {
                xme_hal_time_timeHandle_t currentTime = xme_hal_time_getCurrentTime();
                xme_hal_time_timeInterval_t timeInterval = xme_hal_time_getTimeIntervalBetween(lastRequestTime, currentTime);

                // Check if time interval for retry is up
                if (timeInterval >= retryInterval)
                {
                    doSend = true;
                }
            }
        }

        // PROTECTED REGION END
    }
    
    status[0] = xme_core_login_loginClientComponentWrapper_writePortOutRequest(portOutRequestDataPtr);
    
    {
        // PROTECTED REGION ID(XME_CORE_LOGIN_LOGINCLIENTSENDREQUESTFUNCTION_STEP_2_C) ENABLED START

        if (XME_STATUS_SUCCESS != status[0])
            XME_LOG(XME_LOG_DEBUG, "[loginClientSendRequestFunction] Failed to write the Login Request to port %d\n", status[0]);

        // PROTECTED REGION END
    }
}

void
xme_core_login_loginClientSendRequestFunction_fini
(
    xme_core_login_loginClientComponent_config_t* const componentConfig
)
{
    // PROTECTED REGION ID(XME_CORE_LOGIN_LOGINCLIENTSENDREQUESTFUNCTION_TERMINATE_C) ENABLED START

    // Nothing to do

    XME_UNUSED_PARAMETER(componentConfig);

    // PROTECTED REGION END
}

// PROTECTED REGION ID(XME_CORE_LOGIN_LOGINCLIENTSENDREQUESTFUNCTION_IMPLEMENTATION_C) ENABLED START

// PROTECTED REGION END
